/**
 *  @file SDLZoomDrawer.h
 *
 *  @date 28-nov-2009
 *  @author Ives van der Flaas
 */

#ifndef SDLZOOMDRAWER_H_
#define SDLZOOMDRAWER_H_

#include <SDL.h>
#include <tr1/memory>
#include "vector2.h"


namespace si_sdl
{
/**
 * Singelton that takes a surface, checks if it needs to be zoomed or not and does accordingly.
 * It then draws the surface at the correct location on screen.
 *
 * It will letterbox or pillarbox to keep the 4:3 ratio.
 */
class SDLZoomDrawer
{
public:
	/**
	 * Returns the instance of this class
	 * @return The instance
	 */
	static std::tr1::shared_ptr<SDLZoomDrawer> get()
	{
		static std::tr1::shared_ptr<SDLZoomDrawer> fInstance(new SDLZoomDrawer());
		return fInstance;
	}

	/**
	 * Will be called when the window is resized.
	 * Because all sizes are virtual, all images need to be resized.
	 */
	void resize();

	/**
	 * Draws original at size "virtualSize" at "virtualPosition". If possible, we'll use "resized" as
	 * a buffered & resized version of original. Always send a (potentially empty) SDL_Surf to "resized"
	 * and send it the next time you call draw. This "resized" will be filled by draw().
	 *
	 * VirtualPosition is a position in the normal -4,4 and -3,3 range. Idem dito for
	 * virtualSize.
	 * @param original The original (big-sized) SLD_Surf
	 * @param resized Will fill this with a resized version of "original". Please resend prev result!
	 * @param virtualSize Virtual size of the object
	 * @param virtualPosition Virtual position of the object
	 */
	void draw(std::tr1::shared_ptr<SDL_Surface> original,
			std::tr1::shared_ptr<SDL_Surface>& resized,
			const si::Vector2& virtualSize,
			const si::Vector2& virtualPosition);

	/**
	 * Draws "original" at position in parameter, real size,
	 * relative to the screen offsets (pillarboxed & letterboxed).
	 * @param original The image to be drawn
	 * @param position Position on the screen te be drawn.
	 */
	void drawNoScale(std::tr1::shared_ptr<SDL_Surface> original, const si::Vector2& position);
	virtual ~SDLZoomDrawer();


	/**
	 * Returns the size this object SHOULD have on a real screen. The height is based on it's
	 * virtual size (in real draw it's height is based on the aspect ratio of the image).
	 * @param virtualSize
	 * @param realSize Send an empty vector and I'll fill it with the objecs on screen size
	 * @param offset Send an empty vector and I'll fill it with absolute screen offset
	 * @return
	 */
	void requestRealSizeAndOffset(si::Vector2 virtualSize, si::Vector2&realSize, si::Vector2& offset);

	/**
	 * Returns how big the drawable region of the screen is (in pixels).
	 * @return
	 */
	si::Vector2 requestDrawableRegion() const;

private:
	SDLZoomDrawer();

	const double fVirtualScreenWidth;
	const double fVirtualScreenHeight;

	int fAdjustedScreenWidth;
	int fAdjustedScreenHeight;

	si::Vector2 fScreenOffset;


};

}

#endif /* SDLZOOMDRAWER_H_ */
